package com.lubase.dingding.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.lubase.dingding.service.DingProcessService;
import com.lubase.model.DbEntity;
import com.lubase.orm.QueryOption;
import com.lubase.orm.extend.remote.UserInfoByCodeServiceImpl;
import com.lubase.orm.service.AppHolderService;
import com.lubase.orm.service.DataAccess;
import com.lubase.orm.util.TableFilterWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;

@Slf4j
@Service
public class DingProcessServiceImpl implements DingProcessService {
    @Autowired
    DataAccess dataAccess;

    @Autowired
    UserInfoByCodeServiceImpl userInfoByCodeService;

    @Autowired
    RestTemplate restTemplate;

    @Value("${dingding.qibao-url:http://101.43.198.190:9612/dingding/getProcessList}")
    String qibaoUrl;

    @Value("${dingding.qibao-token-url:http://101.43.198.190:9612/dingding/getQBToken}")
    String qibaoTokenUrl;
    @Autowired
    AppHolderService appHolderService;

    @Override
    public List<DbEntity> getAllProcessListByUserId(String userId) {
        if (StringUtils.isEmpty(userId)) {
            return List.of();
        }
        QueryOption queryOption = new QueryOption("wf_oins");
        queryOption.setFixField("fins_id.apply_user,fins_id.name,fins_id.service_name,task_name,start_time");
        TableFilterWrapper filterWrapper = TableFilterWrapper.and();
        filterWrapper.eq("process_status", "0");
        filterWrapper.eq("user_id", userId).eq("process_status", "0");
        filterWrapper.in("service_id", String.join(",", getEnableAppList()));
        queryOption.setTableFilter(filterWrapper.build());
        List<DbEntity> list = dataAccess.queryAllData(queryOption).getData();
        list.parallelStream().forEach(item -> {
            item.put("_from", "lubase");
        });

        List<DbEntity> qibaoList = getAllProcessListByUserIdFromQibao();
        if (qibaoList == null) {
            return list;
        }

        qibaoList.parallelStream().forEach(list::add);
        return list;
    }

    private List<String> getEnableAppList() {
        QueryOption queryOption = new QueryOption("wf_service");
        queryOption.setFixField("id,enable_app");
        TableFilterWrapper filterWrapper = TableFilterWrapper.and();
        filterWrapper.eq("enable_app", "1");
        queryOption.setTableFilter(filterWrapper.build());
        List<DbEntity> list = dataAccess.queryAllData(queryOption).getData();
        if (list.isEmpty()) {
            return List.of();
        }
        List<String> listId = new ArrayList<>();
        list.forEach(item -> {
            listId.add(item.get("id").toString());
        });
        return listId;
    }

    @Override
    public List<DbEntity> getAllProcessListByUserCode(String userCode) {
        if (StringUtils.isEmpty(userCode)) {
            return List.of();
        }

        DbEntity userEntity = userInfoByCodeService.getCacheDataByKey(userCode);
        if (userEntity == null) {
            return List.of();
        }
        return getAllProcessListByUserId(userEntity.getId().toString());
    }

    @Override
    public List<DbEntity> getAllProcessListByUserIdFromQibao() {
        try {
            List<DbEntity> list = new ArrayList<>();
            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            HttpHeaders headers = new HttpHeaders();
            headers.add("token", appHolderService.getUser().getToken());
            HttpEntity<MultiValueMap<String, String>> formEntity = new HttpEntity<>(map, headers);
            ResponseEntity<JSONArray> jsonObject = restTemplate.exchange(qibaoUrl, HttpMethod.GET, formEntity, JSONArray.class);
            if (jsonObject.getBody() != null && !jsonObject.getBody().isEmpty()) {
                list = JSONArray.parseArray(jsonObject.getBody().toJSONString(), DbEntity.class);
            }
            list.parallelStream().forEach(item -> {
                item.put("_from", "qibao");
                // 占位符，通过设置此属性 设置REFDATA属性
                if (item.containsKey("refdata")) {
                    JSONObject object = (JSONObject) item.get("refdata");
                    for (String key : object.keySet()) {
                        item.setRefData(key, object.get(key).toString());
                    }
                    item.remove("refdata");
                }

            });
            return list;
        } catch (Exception e) {
            log.error("getAllProcessListByUserIdFromQibao error: " + e);
            return null;
        }
    }

    @Override
    public String  getTokenFromQibao(String deptName,String token) {
        try {
            List<DbEntity> list = new ArrayList<>();
            MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
            HttpHeaders headers = new HttpHeaders();
            headers.add("token",token);
            HttpEntity<MultiValueMap<String, String>> formEntity = new HttpEntity<>(map, headers);
            var url=String.format("%s?deptName=%s",qibaoTokenUrl,deptName);
            ResponseEntity<String> strToken = restTemplate.exchange(url, HttpMethod.GET, formEntity, String.class);
            log.info("返回值{}", JSON.toJSONString(strToken));
            if (strToken.getBody() != null && !strToken.getBody().isEmpty()) {
                return  strToken.getBody();
            }
        } catch (Exception e) {
            log.error("getQBToken error: " + e,e);
            return null;
        }
        return  null;
    }
}
